//+------------------------------------------------------------------+
//|                                                      SignalSystem.mqh |
//|                                  Copyright 2024, MetaQuotes Software |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Software"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// 信号类型枚举
enum ENUM_SIGNAL_TYPE {
    SIGNAL_BUY,           // 买入信号
    SIGNAL_SELL,          // 卖出信号
    SIGNAL_CLOSE_BUY,     // 平多信号
    SIGNAL_CLOSE_SELL,    // 平空信号
    SIGNAL_NONE           // 无信号
};

// 信号来源枚举
enum ENUM_SIGNAL_SOURCE {
    SOURCE_MA,            // 移动平均线
    SOURCE_MACD,          // MACD
    SOURCE_RSI,           // RSI
    SOURCE_BB,            // 布林带
    SOURCE_ADX,           // ADX
    SOURCE_VOLUME,        // 成交量
    SOURCE_CUSTOM         // 自定义
};

// 信号结构
struct Signal {
    ENUM_SIGNAL_TYPE type;        // 信号类型
    ENUM_SIGNAL_SOURCE source;    // 信号来源
    double strength;              // 信号强度
    datetime time;                // 信号时间
    double price;                 // 信号价格
    bool isActive;                // 是否激活
};

// 信号系统类
class CSignalSystem {
private:
    // 信号数组
    Signal signals[];
    
    // 技术指标参数
    int maPeriod;                 // 移动平均线周期
    int macdFastPeriod;           // MACD快线周期
    int macdSlowPeriod;           // MACD慢线周期
    int macdSignalPeriod;         // MACD信号线周期
    int rsiPeriod;                // RSI周期
    int bbPeriod;                 // 布林带周期
    double bbDeviation;           // 布林带标准差
    int adxPeriod;                // ADX周期
    double volumeThreshold;       // 成交量阈值
    
    // 信号强度阈值
    double minSignalStrength;     // 最小信号强度
    
    // 初始化参数
    void InitializeParameters() {
        maPeriod = 20;
        macdFastPeriod = 12;
        macdSlowPeriod = 26;
        macdSignalPeriod = 9;
        rsiPeriod = 14;
        bbPeriod = 20;
        bbDeviation = 2.0;
        adxPeriod = 14;
        volumeThreshold = 1.5;
        minSignalStrength = 0.6;
    }
    
    // 生成移动平均线信号
    void GenerateMASignal() {
        double ma = iMA(_Symbol, PERIOD_CURRENT, maPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
        double prevMa = iMA(_Symbol, PERIOD_CURRENT, maPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);
        double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        
        if(price > ma && price > prevMa) {
            AddSignal(SIGNAL_BUY, SOURCE_MA, 0.8);
        }
        else if(price < ma && price < prevMa) {
            AddSignal(SIGNAL_SELL, SOURCE_MA, 0.8);
        }
    }
    
    // 生成MACD信号
    void GenerateMACDSignal() {
        double macdMain[], macdSignal[];
        ArraySetAsSeries(macdMain, true);
        ArraySetAsSeries(macdSignal, true);
        
        int macdHandle = iMACD(_Symbol, PERIOD_CURRENT, macdFastPeriod, macdSlowPeriod, macdSignalPeriod, PRICE_CLOSE);
        CopyBuffer(macdHandle, 0, 0, 2, macdMain);
        CopyBuffer(macdHandle, 1, 0, 2, macdSignal);
        
        if(macdMain[0] > macdSignal[0] && macdMain[1] <= macdSignal[1]) {
            AddSignal(SIGNAL_BUY, SOURCE_MACD, 0.7);
        }
        else if(macdMain[0] < macdSignal[0] && macdMain[1] >= macdSignal[1]) {
            AddSignal(SIGNAL_SELL, SOURCE_MACD, 0.7);
        }
    }
    
    // 生成RSI信号
    void GenerateRSISignal() {
        double rsi[];
        ArraySetAsSeries(rsi, true);
        
        int rsiHandle = iRSI(_Symbol, PERIOD_CURRENT, rsiPeriod, PRICE_CLOSE);
        CopyBuffer(rsiHandle, 0, 0, 2, rsi);
        
        if(rsi[0] < 30 && rsi[1] < 30) {
            AddSignal(SIGNAL_BUY, SOURCE_RSI, 0.6);
        }
        else if(rsi[0] > 70 && rsi[1] > 70) {
            AddSignal(SIGNAL_SELL, SOURCE_RSI, 0.6);
        }
    }
    
    // 生成布林带信号
    void GenerateBBSignal() {
        double bbUpper[], bbLower[];
        ArraySetAsSeries(bbUpper, true);
        ArraySetAsSeries(bbLower, true);
        
        int bbHandle = iBands(_Symbol, PERIOD_CURRENT, bbPeriod, 0, bbDeviation, PRICE_CLOSE);
        CopyBuffer(bbHandle, 1, 0, 2, bbUpper);
        CopyBuffer(bbHandle, 2, 0, 2, bbLower);
        
        double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        
        if(price < bbLower[0]) {
            AddSignal(SIGNAL_BUY, SOURCE_BB, 0.7);
        }
        else if(price > bbUpper[0]) {
            AddSignal(SIGNAL_SELL, SOURCE_BB, 0.7);
        }
    }
    
    // 生成ADX信号
    void GenerateADXSignal() {
        double adx[];
        ArraySetAsSeries(adx, true);
        
        int adxHandle = iADX(_Symbol, PERIOD_CURRENT, adxPeriod);
        CopyBuffer(adxHandle, 0, 0, 2, adx);
        
        if(adx[0] > 25) {
            double diPlus[], diMinus[];
            ArraySetAsSeries(diPlus, true);
            ArraySetAsSeries(diMinus, true);
            
            CopyBuffer(adxHandle, 1, 0, 2, diPlus);
            CopyBuffer(adxHandle, 2, 0, 2, diMinus);
            
            if(diPlus[0] > diMinus[0]) {
                AddSignal(SIGNAL_BUY, SOURCE_ADX, 0.8);
            }
            else if(diMinus[0] > diPlus[0]) {
                AddSignal(SIGNAL_SELL, SOURCE_ADX, 0.8);
            }
        }
    }
    
    // 生成成交量信号
    void GenerateVolumeSignal() {
        double volume[];
        ArraySetAsSeries(volume, true);
        
        int volumeHandle = iVolumes(_Symbol, PERIOD_CURRENT, VOLUME_TICK);
        CopyBuffer(volumeHandle, 0, 0, 20, volume);
        
        double avgVolume = 0;
        for(int i = 1; i < 20; i++) {
            avgVolume += volume[i];
        }
        avgVolume /= 19;
        
        if(volume[0] > avgVolume * volumeThreshold) {
            double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            double prevPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
            
            if(price > prevPrice) {
                AddSignal(SIGNAL_BUY, SOURCE_VOLUME, 0.6);
            }
            else if(price < prevPrice) {
                AddSignal(SIGNAL_SELL, SOURCE_VOLUME, 0.6);
            }
        }
    }
    
    // 添加信号
    void AddSignal(ENUM_SIGNAL_TYPE type, ENUM_SIGNAL_SOURCE source, double strength) {
        int size = ArraySize(signals);
        ArrayResize(signals, size + 1);
        
        signals[size].type = type;
        signals[size].source = source;
        signals[size].strength = strength;
        signals[size].time = TimeCurrent();
        signals[size].price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        signals[size].isActive = true;
    }
    
    // 清理过期信号
    void CleanupSignals() {
        datetime currentTime = TimeCurrent();
        int size = ArraySize(signals);
        
        for(int i = size - 1; i >= 0; i--) {
            if(currentTime - signals[i].time > 3600) { // 1小时前的信号
                signals[i].isActive = false;
            }
        }
    }
    
public:
    // 构造函数
    CSignalSystem() {
        InitializeParameters();
    }
    
    // 析构函数
    ~CSignalSystem() {
        ArrayFree(signals);
    }
    
    // 设置参数
    void SetParameters(int maPeriod, int macdFastPeriod, int macdSlowPeriod, int macdSignalPeriod,
                      int rsiPeriod, int bbPeriod, double bbDeviation, int adxPeriod,
                      double volumeThreshold, double minSignalStrength) {
        this.maPeriod = maPeriod;
        this.macdFastPeriod = macdFastPeriod;
        this.macdSlowPeriod = macdSlowPeriod;
        this.macdSignalPeriod = macdSignalPeriod;
        this.rsiPeriod = rsiPeriod;
        this.bbPeriod = bbPeriod;
        this.bbDeviation = bbDeviation;
        this.adxPeriod = adxPeriod;
        this.volumeThreshold = volumeThreshold;
        this.minSignalStrength = minSignalStrength;
    }
    
    // 生成信号
    void GenerateSignals() {
        GenerateMASignal();
        GenerateMACDSignal();
        GenerateRSISignal();
        GenerateBBSignal();
        GenerateADXSignal();
        GenerateVolumeSignal();
        CleanupSignals();
    }
    
    // 获取最新信号
    bool GetLatestSignal(Signal &signal) {
        int size = ArraySize(signals);
        if(size == 0) return false;
        
        double maxStrength = 0;
        int maxIndex = -1;
        
        for(int i = 0; i < size; i++) {
            if(signals[i].isActive && signals[i].strength > maxStrength) {
                maxStrength = signals[i].strength;
                maxIndex = i;
            }
        }
        
        if(maxIndex >= 0 && maxStrength >= minSignalStrength) {
            signal = signals[maxIndex];
            return true;
        }
        
        return false;
    }
    
    // 获取所有活跃信号
    int GetActiveSignals(Signal &activeSignals[]) {
        int size = ArraySize(signals);
        int count = 0;
        
        for(int i = 0; i < size; i++) {
            if(signals[i].isActive && signals[i].strength >= minSignalStrength) {
                ArrayResize(activeSignals, count + 1);
                activeSignals[count] = signals[i];
                count++;
            }
        }
        
        return count;
    }
    
    // 添加自定义信号
    void AddCustomSignal(ENUM_SIGNAL_TYPE type, double strength) {
        AddSignal(type, SOURCE_CUSTOM, strength);
    }
    
    // 清除所有信号
    void ClearSignals() {
        ArrayFree(signals);
    }
}; 